const net = require('net');
// const aes = require('../lib/aes');
// const md5 = require('../lib/md5');
// const uuid = require('../lib/uuid');
// const qs = require('qs');
// const shuffle = require('../lib/shuffle');
// const key = '47e43adc6f31eae15b359186fb198256e41e749b38a1963e7e9ba20551a7bf3aa9ce4e69de7e36de17bd9695e88eea3117e1aae02122fa846ee29722ed17e395ea9d82ed8117bac775b11afaaaa7cf3746be24ef658db23e8e8123b8e7e1da863f997aa2ee8e71fad94743ea9ee731a5ebec86becb49e7b6eae6e7';//1ce7213246
// const iv = '42aaeda0a68e724337eefd7658939ed4ea048afe96319f3628985ae74b7eee52a89a9ebce5a7ee86c62a612bfeb5bc9ed6465bec18eba472ddefdebb1ae163c2a496efb1beee1b14933ee197f2fe1e8b81d76e121273d1eb79e75b5847523377eeaa1177713ae4a1da189198a51aa4ca7e6c92862eee9e716a737f';//1e33ae8392
class BridgeServer {
  constructor() {
    this.users = {};
    this.nodes = {};
    this.callbacks = {};
    this.dataTemp = {};
    //this.salt = md5(new Date().getFullYear + '-' + (new Date().getMonth + 1) + '-' + new Date().getDate()).slice(0, 5) + uuid().slice(0, 5);
    this.server = net.createServer(socket => {
      socket.id = socket.remoteAddress + ':' + socket.remotePort;
      //socket.salt = shuffle(this.salt.split('')).join('');
      socket.auth = false;
      socket.ip = socket.address();
      socket.on('data', buffer => {
        let raw = buffer.toString();
        // let salt = socket.auth ? socket.salt : md5(new Date().getFullYear + '-' + (new Date().getMonth + 1) + '-' + new Date().getDate()).slice(0, 10);
        // let c = aes(key + salt, iv + salt);
        try {
          let data = JSON.parse(raw);
          if (data.t === 'auth') {
            if (data.d === 'ljx') {
              socket.auth = true;
              if (data.f === 'user' || data.f === 'node') {
                socket.t = data.f;
                this[data.f + 's'][socket.id] = socket;
                socket.write(JSON.stringify({ t: 'auth', cid: data.cid, ret: 1 }));
                console.log('auth successfully');
              } else {
                console.log('f error');
                socket.end();
              }
            } else {
              console.log('auth error');
              socket.end();
            }
          } else if (data.t === 'get') {
            if (socket.auth) {
              if (this.nodes[data.d.n]) {
                if (data.d.req) {
                  let cid = data.cid;
                  this.callbacks[cid] = (data) => {
                    //salt = socket.salt;
                    //c = aes(key + salt, iv + salt);
                    for (let i = 0; i < data.length; i++) {
                      socket.write(JSON.stringify(data[i]));
                    }
                    //
                    console.log('get successfully');
                  }
                  // salt = this.nodes[data.d.n].salt;
                  // c = aes(key + salt, iv + salt);
                  this.nodes[data.d.n].write(JSON.stringify({ t: 'get', cid: cid, req: data.d.req }));
                } else {
                  socket.write(JSON.stringify({ t: 'get', cid: data.cid, res: null, msg: 'request empty', ret: 0 }));
                }
              } else {
                socket.write(JSON.stringify({ t: 'get', cid: data.cid, res: null, ret: 0, msg: 'no node found' }));
              }
            } else {
              socket.end();
            }
          } else if (data.t === 'show') {
            if (socket.auth === true) {
              if (data.d.t === 'node' || data.d.t === 'user') {
                socket.write(JSON.stringify({
                  t: 'show',
                  cid: data.cid,
                  d: Object.keys(this[data.d.t + 's']),
                  ret: 1
                }));
              } else {
                socket.end();
              }
            } else {
              socket.end();
            }
          } else if (data.t === 'node_res') {
            console.log('on callback');
            if (data.slice === true && data.end !== true) {
              console.log('get slice');
              if (this.dataTemp[data.cid] === undefined) {
                this.dataTemp[data.cid] = [];
              }
              this.dataTemp[data.cid].push(data);
            } else if (data.end === true) {
              console.log('send slice');
              console.log(this.dataTemp[data.cid]);
              this.callbacks[data.cid](this.dataTemp[data.cid]);
              delete this.dataTemp[data.cid];
              delete this.callbacks[data.cid];
            } else if (!data.slice) {
              this.callbacks[data.cid](data);
              delete this.callbacks[data.cid];
            }
          } else {
            socket.write(JSON.stringify({ t: 'none', cid: data.cid, d: null, ret: 0, message: 'none' }));
          }
        } catch (e) {
          //console.log(e);
          console.log('err:' + raw);
          socket.end();
        }
      })
      socket.on('error', () => {
        this.nodes[socket.id] ? delete this.nodes[socket.id] : '';
        this.users[socket.id] ? delete this.users[socket.id] : '';
        socket.destroy();
      })
    });
    this.server.listen(1223, '0.0.0.0', () => {
      console.log('bridge start')
    });
  }
}

new BridgeServer();